package org.example.threadtest;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 生产者-消费者模型
 *
 * 利用Lock实现
 */
// 资源
class Res2{
    public String username;
    public String sex;
    int count;
    public boolean flag = false; // false时生产者生产,消费者等待;  true时生产者等待,消费者消费

    // 写资源
    public void write() {

        if (count == 0) {
            username = "小红";
            sex = "女";
        } else {
            username = "小军";
            sex = "男";
        }
        // 计算奇数或者偶数
        count = (count + 1) % 2;

    }
    // 读资源
    public void read() {

        System.out.println(Thread.currentThread().getName() + "\t" + username + "," + sex);

    }
}

// 写
class Out2 extends Thread{

    Res2 res;
    Lock lock;
    Condition condition;

    public Out2(Res2 res,Lock lock,Condition condition) {
        this.res = res;
        this.lock = lock;
        this.condition = condition;
    }
    @Override
    public void run() {
        // 写操作
        while (true) {
            lock.lock();
            try{
                if (res.flag) { // 如果flag为false，生产者生产；否则等待
                    try {
                       condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                System.out.println(Thread.currentThread().getName()+"\t开始写资源...");
                res.write();
                res.flag = true;
                condition.signal();
            }finally {
                lock.unlock();
            }
        }
    }
}


// 读
class Input2 extends Thread {
    Res2 res;
    Lock lock;
    Condition condition;
    public Input2(Res2 res,Lock lock,Condition condition) {
        this.res = res;
        this.lock = lock;
        this.condition = condition;
    }
    @Override
    public void run() {
        // 读操作
        while (true) {
            lock.lock();
            try{
                if (!res.flag) {//如果为flag为false，消费者等待，否则消费
                    try {
                        condition.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                res.read();
                res.flag = false;
                condition.signal();
            }finally {
                lock.unlock();
            }
        }
    }
}

public class OutputThread2 {
    public static void main(String[] args){
        Res2 res = new Res2();
        Lock lock = new ReentrantLock();
        Condition condition = lock.newCondition();
        Out2 out = new Out2(res,lock,condition);
        Input2 input = new Input2(res,lock,condition);
        out.setName("生产者");
        input.setName("消费者");
        out.start();
        input.start();
    }
}
